﻿using System;
using System.Linq;
using Aluetjen.EmailService.Domain.Gateways;
using Aluetjen.EmailService.Domain.Infrastructure;
using Aluetjen.EmailService.Domain.Models.Message;
using Aluetjen.EmailService.Domain.Models.Pipeline;
using log4net;

namespace Aluetjen.EmailService.Domain.Services
{
    public class DispatchService : IPipelineService
    {
        private readonly ILog _log = LogManager.GetLogger(typeof (DispatchService));
        private readonly IRepository<Gateway> _gatewayRepository;
        private readonly Func<string, IGatewayImpl> _gatewayImplFactory;

        public decimal Priority
        {
            get { return decimal.MaxValue; }
        }

        public DispatchService(IRepository<Gateway> gatewayRepository, Func<string, IGatewayImpl> gatewayImplFactory)
        {
            _gatewayRepository = gatewayRepository;
            _gatewayImplFactory = gatewayImplFactory;
        }

        public void ProcessMessage(MailMessage message)
        {
            var dispatchToGateways = _gatewayRepository.All().Where(g => g.DispatchToGateway);

            foreach(var gateway in dispatchToGateways)
            {
                var gatewayImpl = _gatewayImplFactory(gateway.Name);

                try
                {
                    gatewayImpl.Send(message);
                }
                catch (GatewayCommunicationException exception)
                {
                    if (gateway.IgnoreFailure)
                    {
                        _log.ErrorFormat("Mail dispatch failed in {1} due to gateway exception. Dispatch continues and won't be retired: {0}", exception, gateway.Name);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }
    }
}